package com.laolang.pluto.module.sys.logic.impl;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.stereotype.Service;

import com.laolang.pluto.common.logic.impl.BaseLogicImpl;
import com.laolang.pluto.module.sys.entity.SysMenu;
import com.laolang.pluto.module.sys.logic.SysMenuLogic;
import com.laolang.pluto.module.sys.mapstruct.SysMenuMapStruct;
import com.laolang.pluto.module.sys.pojo.vo.SysMenuTreeVo;
import com.laolang.pluto.module.sys.service.SysMenuService;

import cn.hutool.core.collection.CollUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * @author laolang
 * @date 2021-08-09 02:38
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class SysMenuLogicImpl extends BaseLogicImpl implements SysMenuLogic {
    private final SysMenuService sysMenuService;
    private final SysMenuMapStruct sysMenuMapStruct;

    @Override
    public List<SysMenuTreeVo> listTree() {
        // 添加首页菜单
        List<SysMenuTreeVo> tree = new ArrayList<>();


        // 查出所有
        List<SysMenu> entityList = sysMenuService.list();
        // 如果菜单为空
        if (CollUtil.isEmpty(entityList)) {
            return tree;
        }

        // 根分类
        tree = entityList.stream()
                .filter(entity -> 0L == entity.getParentId())
                .map(sysMenuMapStruct::entity2treevo)
                .collect(Collectors.toList());

        // 分类树 map 缓存
        Map<Long, SysMenuTreeVo> treeMap = tree.stream().collect(Collectors.toMap(SysMenuTreeVo::getId, t -> t));
        // 非根分类按照parentId和sort排序
        List<SysMenu> notRootList = entityList.stream()
                .filter(t -> 0L != t.getParentId())
                .sorted(Comparator.comparing(SysMenu::getParentId).thenComparing(SysMenu::getOrderNum))
                .collect(Collectors.toList());
        if (CollUtil.isEmpty(notRootList)) {
            return tree;
        }

        // 非根分类添加到树中
        notRootList.forEach(node -> {
            SysMenuTreeVo parent = treeMap.get(node.getParentId());
            if (null != parent) {
                SysMenuTreeVo treeNode = sysMenuMapStruct.entity2treevo(node);
                parent.getChild().add(treeNode);
                treeMap.put(treeNode.getId(), treeNode);
            }
        });

        return tree;
    }
}
